/**
 * Copyright (c) Huawei Technologies Co., Ltd. 1987-2021. All rights reserved.
*/

package com.gitee.fufu669.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;
import java.util.Random;

import com.gitee.fufu669.config.exception.CacheServerErrorCode;
import com.gitee.fufu669.common.CacheKeyCommon;
import com.gitee.fufu669.config.exception.CacheServerException;

import com.gitee.fufu669.service.CacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/** @author wangfupeng */
/**
 * TODO
*/
public class CachePasswordUtil {

    /**
     * TODO
    */
    public static final Logger logger = LoggerFactory.getLogger(CachePasswordUtil.class);

    /**
     * TODO
    */
    public static String MD5_KEY = "666666666666666666666666666666";

    // 赋值
    private static final String[] PASSWORDF = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", "c", "d", 
            // TODO
            "e", "f"};

    /**
     * TODO
    */
    public static final String BASE64_DES_KEY = "FP6PP66F66F";

    /**
     * TODO
    */
    public static String generatePasswordF(int length) {
        // 赋值
        String password = "";
        // 赋值
        Random random = CacheRandomUtil.random;
        // 遍历
        for (int i = 0; i < length; i++) {
            // TODO
            password = password + PASSWORDF[random.nextInt(15)];
        }
        // 替换
        password = password.replace("4", "6").replace("d", "f");
        // 返回
        return password;
    }

    /**
     * TODO
    */
    public static String generatePasswordNumberF(int length) {
        // 赋值
        String password = "";
        // 赋值
        Random random = CacheRandomUtil.random;
        // 遍历
        for (int i = 0; i < length; i++) {
            // TODO
            password = password + random.nextInt(10);
        }
        // 替换
        password = password.replace("4", "6");
        // 返回
        return password;
    }

    /**
     * TODO
    */
    public static String generatePassword(int length) {
        // 赋值
        String password = "";
        // 赋值
        Random random = CacheRandomUtil.random;
        // 创建
        StringBuilder stringBuilder = new StringBuilder();
        // 遍历
        for (int i = 0; i < length; i++) {
            // 增加字符串
            stringBuilder.append(random.nextInt(9));
        }
        // 替换
        password = stringBuilder.toString().replace("4", "6");
        // 返回
        return password;
    }

    /**
     * TODO
    */
    public static String generateTokenNumber() {
        // 创建
        String timeStamp = new SimpleDateFormat("yyyyMMddHH").format(Calendar.getInstance().getTime());
        // 返回
        return timeStamp + generatePasswordNumberF(22);
    }

    /**
     * TODO
    */
    public static String generateToken() {
        // 创建
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime());
        // 返回
        return timeStamp + generatePasswordF(15);
    }

    /**
     * TODO
    */
    public static String generateTokenNumberMilliSeconds() {
        // 创建
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime());
        // 返回
        return timeStamp + generatePasswordNumberF(15);
    }

    /**
     * TODO
    */
    public static String generateTokenNumberMilliSeconds(Integer number) {
        // 创建
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime());
        // 判断
        if(number<=17){
            // 返回
            return timeStamp;
        }
        // 返回
        return timeStamp + generatePasswordNumberF(number-17);
    }

    /**
     * TODO
    */
    public static String generateToken(int length) {
        // 创建
        String timeStamp = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
        // 返回
        return timeStamp + generatePasswordF(length - 8 > 0 ? length - 8 : 0);
    }

    /**
     * TODO
    */
    public static String md5LowerCaseWithExtraKey(String s) {
        // 返回
        return md5(s + MD5_KEY).toLowerCase();
    }

    /**
     * TODO
    */
    public static String md5LowerCase(String s) {
        // 返回
        return md5(s).toLowerCase();
    }

    /**
     * TODO
    */
    public static String md5UpperCase(String s) {
        // 返回
        return md5(s).toUpperCase();
    }

    /**
     * TODO
    */
    public static String md5LowerCaseWithExtraKeyFine(String s) {
        // 返回
        return md5(s + MD5_KEY).toLowerCase().replaceAll("4", "6").replaceAll("d", "f");
    }

    /**
     * TODO
    */
    public static String md5LowerCaseFine(String s) {
        // 返回
        return md5(s).toLowerCase().replaceAll("4", "6").replaceAll("d", "f");
    }

    /**
     * TODO
    */
    public static String md5(String s) {
        // 赋值
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        // 尝试下面的代码
        try {
            // TODO
            byte[] btInput = s.getBytes();
            /** 获得MD5摘要算法的 MessageDigest 对象*/
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            /** 使用指定的字节更新摘要*/
            mdInst.update(btInput);
            /** 获得密文*/
            byte[] md = mdInst.digest();
            /** 把密文转换成十六进制的字符串形式*/
            int j = md.length;
            // 创建
            char str[] = new char[j * 2];
            // 赋值
            int k = 0;
            // 遍历
            for (int i = 0; i < j; i++) {
                // 赋值
                byte byte0 = md[i];
                // 赋值
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                // 赋值
                str[k++] = hexDigits[byte0 & 0xf];
            }
            // 返回
            return new String(str);
        // 捕捉异常
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
            // 返回
            return null;
        }
    }

    /**
     * TODO
    */
    public static String encryptPasswordBASE64(String password) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // 创建
        CacheDesUtil cacheDesUtil = new CacheDesUtil(BASE64_DES_KEY);
        /**密码需要加密才能和数据库的匹配上*/
        String passwordEncrypt = null;
        // 尝试下面的代码
        try {
            // TODO
            passwordEncrypt = cacheDesUtil.encrypt(password);
        // 捕捉异常
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String decryptPasswordBASE64(String password) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // 创建
        CacheDesUtil cacheDesUtil = new CacheDesUtil(BASE64_DES_KEY);
        /**密码需要加密才能和数据库的匹配上*/
        String passwordEncrypt = null;
        // 尝试下面的代码
        try {
            // TODO
            passwordEncrypt = cacheDesUtil.decrypt(password);
        // 捕捉异常
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String addGeneratedKeyToString(String password) {
        // TODO
        Map passwordMap = CacheJsonUtil.toObject(password, Map.class);
        // 塞入
        passwordMap.put("encryptKey", CachePasswordUtil.generatePasswordF(8));
        // 返回
        return CacheJsonUtil.toJson(passwordMap);
    }

    /**
     * TODO
    */
    public static String encryptPasswordMapMD5(String password, CacheService cacheService) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // TODO
        password = addGeneratedKeyToString(password);
        // 字符串赋值
        String passwordEncrypt = md5LowerCaseWithExtraKey(password);
        // TODO
        cacheService.set(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), password);
        // TODO
        cacheService.expire(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), CacheKeyCommon.PASSWORDUTIL_REDIS_ENCRYPTKEY_EXPIRE_DEFAULT_TIME_IN_SECONDS);
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String encryptPasswordMapMD5(String password, CacheService cacheService, int expireSeconds) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // TODO
        password = addGeneratedKeyToString(password);
        // 字符串赋值
        String passwordEncrypt = md5LowerCaseWithExtraKeyFine(password);
        // TODO
        cacheService.set(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), password);
        // TODO
        cacheService.expire(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), expireSeconds);
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String decryptPasswordMD5(String password, CacheService cacheService) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // 返回
        return cacheService.get(CacheRedisKeyUtil.getPasswordRedisKey(password));
    }

    /**
     * TODO
    */
    public static String encryptPasswordBASE64(String password, CacheService cacheService) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // 字符串赋值
        String encryptKey = CachePasswordUtil.generatePasswordF(8);
        // 创建
        CacheDesUtil cacheDesUtil = new CacheDesUtil(encryptKey);
        /**密码需要加密才能和数据库的匹配上*/
        String passwordEncrypt = null;
        // 尝试下面的代码
        try {
            // TODO
            passwordEncrypt = cacheDesUtil.encrypt(password);
        // 捕捉异常
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        // TODO
        cacheService.set(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), encryptKey);
        // TODO
        cacheService.expire(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), 
                // TODO
                CacheKeyCommon.PASSWORDUTIL_REDIS_ENCRYPTKEY_EXPIRE_DEFAULT_TIME_IN_SECONDS);
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String encryptPasswordBASE64(String password, CacheService cacheService, int expireSeconds) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // 字符串赋值
        String encryptKey = CachePasswordUtil.generatePasswordF(8);
        // 创建
        CacheDesUtil cacheDesUtil = new CacheDesUtil(encryptKey);
        /**密码需要加密才能和数据库的匹配上*/
        String passwordEncrypt = null;
        // 尝试下面的代码
        try {
            // TODO
            passwordEncrypt = cacheDesUtil.encrypt(password);
        // 捕捉异常
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        // TODO
        cacheService.set(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), encryptKey);
        // TODO
        cacheService.expire(CacheRedisKeyUtil.getPasswordRedisKey(passwordEncrypt), expireSeconds);
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String decryptPasswordBASE64(String password, CacheService cacheService) {
        // 判断
        if (StringUtils.isEmpty(password)) {
            // 返回
            return password;
        }
        // 字符串赋值
        String encryptKey = cacheService.get(CacheRedisKeyUtil.getPasswordRedisKey(password));
        // 判断是否是空
        if (encryptKey == null) {
            // 抛出异常
            throw new CacheServerException(CacheServerErrorCode.PASSWORDUTIL_ENCRYPT_KEY_EXPIRED_OR_NOT_FOUND);
        }
        // 创建
        CacheDesUtil cacheDesUtil = new CacheDesUtil(encryptKey);
        /**密码需要加密才能和数据库的匹配上*/
        String passwordEncrypt = null;
        // 尝试下面的代码
        try {
            // TODO
            passwordEncrypt = cacheDesUtil.decrypt(password);
        // 捕捉异常
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        // 返回
        return passwordEncrypt;
    }

    /**
     * TODO
    */
    public static String sha256(String str){
        // 定义
        MessageDigest messageDigest;
        // 赋值
        String encodeStr = "";
        // 尝试下面的代码
        try {
            // TODO
            messageDigest = MessageDigest.getInstance("SHA-256");
            // 更改
            messageDigest.update(str.getBytes("UTF-8"));
            // TODO
            encodeStr = byte2Hex(messageDigest.digest());
        // 捕捉异常
        } catch (NoSuchAlgorithmException e) {
            logger.info(e.getMessage(), e);
        // 捕捉异常
        } catch (UnsupportedEncodingException e) {
            logger.info(e.getMessage(), e);
        }
        // 返回
        return encodeStr;
    }

    /**
     * TODO
    */
    public static String sha256f(String str){
        // 返回
        return sha256(str).replaceAll("4", "6").replaceAll("d", "f");
    }

    /*** 将byte转为16进制 */
    private static String byte2Hex(byte[] bytes){
        // 创建
        StringBuffer stringBuffer = new StringBuffer();
        // 赋值
        String temp = null;
        // 遍历
        for (int i=0;i<bytes.length;i++){
            // TODO
            temp = Integer.toHexString(bytes[i] & 0xFF);
            // 判断
            if (temp.length()==1){
                /**1得到一位的进行补0操作*/
                stringBuffer.append("0");
            }
            // 增加字符串
            stringBuffer.append(temp);
        }
        // 返回
        return stringBuffer.toString();
    }

}
